package model.maze;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.PrintWriter;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Observable;
import java.util.Random;
import audio.AudioPlayer;


import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;

import audio.AudioPlayer;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
import com.thoughtworks.xstream.io.xml.StaxDriver;

import model.Model;

public class MazeModel extends Observable implements Model, Serializable
{
	// SerializationVersionUID	
	private static final long serialVersionUID = 302986062L;

	// Data Members
	private int[][] board;
	private int N,M;
	private ArrayList<String> emptySlots;
	private int score;
	private LinkedList<int[][]> boardUndoLinkedList;
	private LinkedList<Integer> scoreUndoLinkedList;
	private LinkedList<ArrayList<String>> emptySlotsUndoLinkedList;
	private XStream xstream;
	private AudioPlayer bgMusic;
	private int muteFlag;
	private int[] currentLocation;
	private int x;
	private int y;

	// Statics
	private static final int EMPTY = 0;
	private static final int STAIGHT_MOVEMENT_SCORE = 10;
	private static final int DIAGONAL_MOVEMENT_SCORE = 15;
	// MazeModel CTOR
	public MazeModel()
	{
		this.N = 20;
		this.M = 20;
		this.bgMusic = new AudioPlayer("/sounds/dna.mp3");
		
		this.board = new int[N][M];
		    
		
		
		for (int i = 0; i < this.N; i++)
			for (int j = 0; j < this.M; j++)
				this.board[i][j] = MazeModel.EMPTY;


		this.emptySlots = new ArrayList<String>();
		initializeEmptySlots();

		this.boardUndoLinkedList = new LinkedList<int[][]>();
		this.scoreUndoLinkedList = new LinkedList<Integer>();
		this.emptySlotsUndoLinkedList = new LinkedList<ArrayList<String>>();

		this.score = 0;

		xstream = new XStream();
		xstream.alias("MazeModel", MazeModel.class);

		setChanged();
		notifyObservers();
	}

	// Fill the emptySlots ArrayList with every slot on the board
	private void initializeEmptySlots()
	{

	/*	for (int i = 0; i < this.N; i++)
		   for (int j = 0; j < this.M; j++)
			   if((double)this.GetRandomNumber() > (double)N/(2))
			   {
			    this.board[i][j] = 0;
			   }
			   else 
			   {
				   this.board[i][j] = -1;
			   }
		
		
		if(this.GetRandomNumber() > this.N/2)
		{
			this.board[0][this.GetRandomNumber()] = MOUSE;
			
		}
		else this.board[N-1][this.GetRandomNumber()] = MOUSE;
		
		if(this.GetRandomNumber() > this.N/2)
		{
			this.board[this.GetRandomNumber()][M-1] = GOAL;
			
		}
		else this.board[this.GetRandomNumber()][0] = GOAL;*/
		this.setScore(EMPTY);
		int i = GetRandomNumber();
		this.board = buildMaze(i);
		currentLocation = getCurrentLocation();
		this.x = currentLocation[1];
		this.y = currentLocation[0];
		
		
	}


	

	

	public void moveUp() 
	{
		  
		// TODO integrate isGameOver into the game somehow
      
        
		boolean moved = false;
	

		addCurrentBoardToUndo();
		
	
        try
        {
        if(board[y-1][x] == 0)
        {
        	board[y-1][x] = 1;
        	board[y][x] = 0;
        	 moved = true;
            y--;
            addScore(STAIGHT_MOVEMENT_SCORE);
        }
        else if(board[y-1][x] == 2)
        {
        	initializeEmptySlots();
        	 moved = true;
        }
        }
        catch(Exception e)
        {
        
        }

		if (moved == true)
		{
			
			

			// raise a flag of a change
			setChanged();

			// Notify all of the observers that a change has been made
			notifyObservers();
		}
		}
		

	@Override
	// Move every slot downwards.
	// Move each column separately using the moveEntireCol method.
	// After that, addRandomNumAtRandomSlot.
	// Lastly, notifyAllObservers.
	public void moveDown() 
	{
		// TODO integrate isGameOver into the game somehow
       
       
		boolean moved = false;
	

		addCurrentBoardToUndo();
	
        try
        {
        if(board[y+1][x] == 0)
        {
        	board[y+1][x] = 1;
        	board[y][x] = 0;
        	 moved = true;
         y++;
         addScore(STAIGHT_MOVEMENT_SCORE);
        }
        else if(board[y+1][x] == 2)
        {
        	initializeEmptySlots();
        	 moved = true;
        }
        }
        catch(Exception e)
        {
        
        }

		if (moved == true)
		{
			
			

			// raise a flag of a change
			setChanged();

			// Notify all of the observers that a change has been made
			notifyObservers();
		}
		
	}


		



	@Override
	// Move every slot left.
	
	// Lastly, notifyAllObservers.
	public void moveLeft() 
	{
		 
		boolean moved = false;
		

		addCurrentBoardToUndo();
		
	
        try
        {
        if(board[y][x-1] == 0)
        {
        	board[y][x-1] = 1;
        	board[y][x] = 0;
        	 moved = true;
            x--;
            addScore(STAIGHT_MOVEMENT_SCORE);
        }
        else if(board[y][x-1] == 2)
        {
        	initializeEmptySlots();
        	 moved = true;
        }
        }
        catch(Exception e)
        {
        
        }

		if (moved == true)
		{
			
			

			// raise a flag of a change
			setChanged();

			// Notify all of the observers that a change has been made
			notifyObservers();
		}
	
	}

	@Override
	// Move every slot right.


	// Lastly, notifyAllObservers.
	public void moveRight() 
	{
		 
		boolean moved = false;
		

		addCurrentBoardToUndo();
		
	
        try
        {
        if(board[y][x+1] == 0)
        {
        	board[y][x+1] = 1;
        	board[y][x] = 0;
        	 moved = true;
            x++;
            addScore(STAIGHT_MOVEMENT_SCORE);
        }
        else if(board[y][x+1] == 2)
        {
        	initializeEmptySlots();
        	 moved = true;
        }
        }
        catch(Exception e)
        {
        
        }

		if (moved == true)
		{
			
			

			// raise a flag of a change
			setChanged();

			// Notify all of the observers that a change has been made
			notifyObservers();
		}
	
	}

	


	@Override
	// Get the board integer 2D-array
	public int[][] getData() 
	{
		return this.board;
	}

	// Get the score value
	public int getScore()
	{
		return this.score;
	}

	// Add an integer to the score
	private int addScore(int toAdd)
	{
		this.score += toAdd;
		return this.score;
	}

	@Override
	// Start the game
	public void startGame() 
	{
		//BG Music
		if(muteFlag == 1)
		{
			bgMusic.stop();
		}
		else
		{
			bgMusic.play();	
		}
		
		this.score = 0;

		this.board = new int[N][M];

		for (int i = 0; i < this.N; i++)
			for (int j = 0; j < this.M; j++)
				this.board[i][j] = MazeModel.EMPTY;

		//this.emptySlots.clear();
		initializeEmptySlots();

		clearUndoLinkedLists();



		setChanged();
		notifyObservers();
	}

	private void addCurrentBoardToUndo() 
	{
		int[][] tempBoard = new int[this.N][this.M];
		for (int i = 0; i < this.N; i++)
			tempBoard[i] = Arrays.copyOf(this.board[i], this.board.length);
		this.boardUndoLinkedList.addFirst(tempBoard);

		this.scoreUndoLinkedList.addFirst(this.score);		
		this.emptySlotsUndoLinkedList.addFirst(new ArrayList<String>(this.emptySlots));
	}

	private void clearUndoLinkedLists()
	{
		this.boardUndoLinkedList.clear();
		this.scoreUndoLinkedList.clear();
		this.emptySlotsUndoLinkedList.clear();
	}

	@Override
	// Undo the last move
	public void undo() 
	{
		if (!this.boardUndoLinkedList.isEmpty())
		{
			int[][] tempBoard = boardUndoLinkedList.pollFirst();

			for (int i = 0; i < this.N; i++)
				for (int j = 0; j < this.M; j++)
					this.board[i][j] =  tempBoard[i][j];

			this.score = this.scoreUndoLinkedList.pollFirst();

			ArrayList<String> tempEmptySlots = emptySlotsUndoLinkedList.pollFirst();
			this.emptySlots.clear();
			this.emptySlots.addAll(tempEmptySlots);
			this.currentLocation = this.getCurrentLocation();
			  this.y = currentLocation[0];
		        this.x = currentLocation[1];
			setChanged();
			notifyObservers();
			
		}
	}
	@Override
	//Mute
	public void mute()
	{
		if(getMuteFlag()==0)
		{
		bgMusic.stop();
		setMuteFlag(1);
		}
		else
		{
		bgMusic.play();
		setMuteFlag(0);
		}	
	}

	@Override
	// Return the amount of rows for the game (N)
	public int getRows() 
	{
		return this.N;
	}

	@Override
	// Return the amount of columns for the game (N)
	public int getCols() 
	{
		return this.M;
	}

	@Override
	public void save(String fileLocation) 
	{
		System.out.println("Save: " + fileLocation);

		FileOutputStream fileOut = null;

		try
		{	
			fileOut = new FileOutputStream(fileLocation);

			String xml = xstream.toXML(this.CopyBeforeXML());

			fileOut.write(xml.getBytes());

			MazeModel newModel = (MazeModel) xstream.fromXML(new FileReader(fileLocation));

			fileOut.close();
		} 
		catch (IOException e) { e.printStackTrace(); }
	}

	public MazeModel CopyBeforeXML()
	{
		MazeModel newModel = new MazeModel();
		newModel.board = this.board;
		newModel.boardUndoLinkedList = this.boardUndoLinkedList;
		newModel.N = this.N;
		newModel.M = this.M;
		newModel.score = this.score;
		newModel.scoreUndoLinkedList = this.scoreUndoLinkedList;
		newModel.emptySlots = this.emptySlots;
		newModel.emptySlotsUndoLinkedList = this.emptySlotsUndoLinkedList;

		return newModel;
	}

	@Override
	public void load(String fileLocation) 
	{		
		FileInputStream fileIn;
		try
		{
			fileIn = new FileInputStream(fileLocation);

			MazeModel newModel = ((MazeModel) xstream.fromXML(new FileReader(fileLocation)));

			CopyAfterXML(newModel);
		}
		catch (IOException e) { e.printStackTrace(); }

		setChanged();
		notifyObservers();
	}

	private void CopyAfterXML(MazeModel newModel) 
	{
		this.board = newModel.board;
		this.boardUndoLinkedList = newModel.boardUndoLinkedList;
		this.N = newModel.N;
		this.score = newModel.score;
		this.scoreUndoLinkedList = newModel.scoreUndoLinkedList;
		this.emptySlots = newModel.emptySlots;
		this.emptySlotsUndoLinkedList = newModel.emptySlotsUndoLinkedList;	
	}

	private int getN()
	{
		return this.N;
	}
	private int getM()
	{
		return this.M;
	}

	private void setN(int newN)
	{
		this.N = newN;;
	}
	private void setM(int newM)
	{
		this.M = newM;;
	}

	public int[][] getBoard() 
	{
		return board;
	}

	public void setBoard(int[][] board) 
	{
		this.board = board;
	}

	public void setScore(int score) {
		this.score = score;
	}

	@Override
	public String toString()
	{
		String str = new String();

		for (int i = 0; i < this.N; i++)
		{
			for (int j = 0; j < this.M; j++)
			{
				str = str.concat(Integer.toString(this.board[i][j]));
				str = str.concat("\t");
			}
			str = str.concat("\n");
		}

		return str;
	}

	public int getMuteFlag() {
		return muteFlag;
	}

	public int setMuteFlag(int muteFlag) {
		this.muteFlag = muteFlag;
		return muteFlag;
	}

	@Override
	public void moveUpRight() {
		boolean moved = false;
		

		addCurrentBoardToUndo();
		
        try
        {
        if(board[y-1][x+1] == 0)
        {
        	board[y-1][x+1] = 1;
        	board[y][x] = 0;
        	 moved = true;
            x++;
            y--;
            addScore(DIAGONAL_MOVEMENT_SCORE);
        }
        else if(board[y-1][x+1] == 2)
        {
        	initializeEmptySlots();
        	 moved = true;
        }
        }
        catch(Exception e)
        {
        
        }

		if (moved == true)
		{
			
			

			// raise a flag of a change
			setChanged();

			// Notify all of the observers that a change has been made
			notifyObservers();
		}
		
	}

	@Override
	public void moveUpLeft() {
		boolean moved = false;
		
		addCurrentBoardToUndo();
		
        try
        {
        if(board[y-1][x-1] == 0)
        {
        	board[y-1][x-1] = 1;
        	board[y][x] = 0;
        	 moved = true;
            x--;
            y--;
            addScore(DIAGONAL_MOVEMENT_SCORE);
        }
        else if(board[y-1][x-1] == 2)
        {
        	initializeEmptySlots();
        	 moved = true;
        }
        }
        catch(Exception e)
        {
        
        }

		if (moved == true)
		{
			
			

			// raise a flag of a change
			setChanged();

			// Notify all of the observers that a change has been made
			notifyObservers();
		}
		
		
	}

	@Override
	public void moveDownLeft() {
		boolean moved = false;
		

		addCurrentBoardToUndo();
		
        try
        {
        if(board[y+1][x-1] == 0)
        {
        	board[y+1][x-1] = 1;
        	board[y][x] = 0;
        	 moved = true;
            x--;
            y++;
            addScore(DIAGONAL_MOVEMENT_SCORE);
        }
        else if(board[y+1][x-1] == 2)
        {
        	initializeEmptySlots();
        	 moved = true;
        }
        }
        catch(Exception e)
        {
        
        }

		if (moved == true)
		{
			
			

			// raise a flag of a change
			setChanged();

			// Notify all of the observers that a change has been made
			notifyObservers();
		}
		
	}

	@Override
	public void moveDownRight() {
		boolean moved = false;


		addCurrentBoardToUndo();
		
        try
        {
        if(board[y+1][x+1] == 0)
        {
        	board[y+1][x+1] = 1;
        	board[y][x] = 0;
        	 moved = true;
            x++;
            y++;
            addScore(DIAGONAL_MOVEMENT_SCORE);
        }
        else if(board[y+1][x+1] == 2)
        {
        	initializeEmptySlots();
        	 moved = true;
        }
        }
        catch(Exception e)
        {
        
        }

		if (moved == true)
		{
			
			

			// raise a flag of a change
			setChanged();

			// Notify all of the observers that a change has been made
			notifyObservers();
		}
		
	}
	
	///Generates a random number for the domain [0,N]
	private int GetRandomNumber()
	{
		return (int)(Math.random() * ((N)));
	}
	
	///Locates the "mouse"
	
	private int[] getCurrentLocation()
	{int i=0,j=0;
	int[] mouseLocation = new int[2];
	
		for(i=0;i<N;i++)
			for(j=0;j<M;j++)
				if(board[i][j]==1)
				{
					 mouseLocation[0] = i;
					 mouseLocation[1] = j;
				}
		
		return mouseLocation;
	}
		private int[][] buildMaze(int choice)
		{
			
			
			if(choice==1 || choice==2 || choice ==9 )
			{
			int[][] maze = new int[][] {{-1,-1,-1,0,2,-1,-1,-1,0,-1,-1,-1,0,-1,0,0,0,0,-1,0},
					                    {-1,0,0,0,-1,-1,0,-1,-1,0,-1,0,-1,-1,-1,0,-1,0,0,-1},
					                    {-1,0,0,0,0,-1,-1,-0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,-1},
					                    {-1,-1,0,-1,0,-1,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,-1},
					                    {0,0,0,-1,0,-1,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1},
					                    {0,-1,-1,0,0,-1,-1,-1,0,0,-1,-1,0,-1,0,-1,-1,-1,-1,0},
					                    {-1,0,-1,0,-1,0,0,-1,-1,-1,-1,0,-1,-1,-1,0,-1,0,-1,0},
					                    {-1,0,0,-1,0,-1,-1,-0,-1,0,-1,0,-1,0,-1,-1,-1,-1,-1,0},
					                    {0,-1,0,-1,0,-1,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,0,-1},
					                    {-1,-1,0,-1,0,-1,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0},
			                            {-1,-1,-1,0,-1,0,-1,-1,0,0,-1,-1,0,-1,0,-1,0,-1,-1,-1},
                                        {-1,0,0,0,-1,-1,0,-1,-1,0,-1,0,-1,-1,-1,0,-1,0,0,-1},
                                        {0,0,0,-1,0,-1,-1,-0,-1,0,0,0,-1,0,-1,0,-1,0,-1,-1},
                                        {-1,-1,0,-1,0,-1,-1,0,-1,0,-1,0,-1,0,-1,0,-1,-1,0,-1},
                                        {-1,-1,0,-1,0,-1,-1,0,-1,-1,-1,0,-1,0,-1,0,-1,-1,0,-1},
                                        {-1,-1,-1,0,-1,-1,-1,0,0,0,-1,-1,0,-1,0,-1,0,-1,-1,0},
                                        {-1,0,0,0,-1,-1,0,-1,-1,0,-1,0,-1,-1,-1,0,-1,0,-1,-1},
                                         {-1,0,0,-1,0,-1,-1,0,-1,0,-1,0,-1,0,-1,0,0,0,-1,0},
                                         {-1,-1,0,-1,0,-1,-1,0,-1,0,-1,0,-1,0,-1,-1,-1,0,0,-1},
                                         {-1,-1,-0,-1,-1,0,-1,0,-1,0,-1,-1,-1,0,-1,-1,-1,1,-1,0}};
			
			return maze;
			}
			else if(choice==3 || choice==4)
			{
			int[][] maze = new int[][] {{-1,-1,-1,0,0,-1,-1,-1,0,-1,-1,-1,0,-1,0,0,0,0,2,0},
					                    {-1,-1,0,-1,0,-1,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,-1},
					                    {-1,-1,0,-1,0,-1,-1,0,-1,0,-1,0,-1,-1,-1,0,-1,-1,0,-1},
					                    {-1,0,0,-1,0,-1,-1,-0,-1,0,-1,0,-1,0,-1,-1,-1,-1,-1,0},
					                    {0,-1,0,-1,0,-1,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,0,-1},
					                    {-1,-1,0,-1,0,-1,-1,0,-1,-1,-1,0,-1,0,-1,0,-1,-1,0,-1},
			                            {-1,-1,-1,0,-1,0,-1,-1,0,0,-1,-1,0,-1,0,-1,0,-1,-1,-1},
                                        {-1,0,0,0,-1,-1,0,-1,-1,0,-1,0,-1,-1,-1,0,-1,0,0,-1},
                                        {0,0,0,-1,0,-1,-1,-0,-1,0,0,0,-1,0,-1,0,-1,0,-1,-1},
                                        {-1,-1,0,-1,0,-1,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0},
                                        {-1,-1,-1,0,-1,-1,-1,0,0,0,-1,-1,0,-1,0,-1,0,-1,-1,0},
                                        {-1,0,0,0,-1,-1,0,-1,-1,0,-1,0,-1,-1,-1,0,-1,0,-1,-1},
                                        {-1,0,0,-1,0,-1,-1,0,-1,0,-1,0,-1,0,-1,0,0,0,-1,0},
                                        {-1,-1,0,-1,0,-1,-1,0,0,-1,-1,0,-1,0,-1,-1,-1,0,0,-1},
                                        {-1,-1,-0,-1,-1,0,-1,0,-1,0,-1,-1,-1,0,-1,-1,-1,0,-1,0},
                                        {0,0,0,-1,0,-1,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1},
 					                    {0,-1,-1,0,0,-1,-1,-1,0,0,-1,-1,0,-1,0,-1,-1,-1,-1,0},
 					                    {-1,0,0,0,-1,-1,0,-1,-1,-1,-1,0,-1,-1,-1,0,-1,0,0,-1},
 					                    {-1,0,0,0,0,-1,-1,-0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,-1},
 					                    {-1,0,-1,0,1,0,0,-1,-1,-1,-1,0,-1,-1,-1,0,-1,0,-1,0}};
			
			return maze;
			}
			
			else if(choice==5 || choice==6 || choice==7 )
			{
			int[][] maze = new int[][] {{-1,-1,-1,0,0,-1,-1,-1,0,-1,-1,-1,0,-1,0,2,0,0,-1,0},  
					                    {0,-1,0,-1,0,-1,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,-1},
					                    {-1,-1,0,-1,0,-1,-1,0,-1,0,-1,0,-1,0,-1,0,-1,-1,0,-1},
                                        {-1,0,0,0,-1,-1,-1,0,-1,0,-1,0,-1,-1,-1,0,-1,0,0,-1},
                                        {0,0,0,-1,0,-1,-1,0,-1,0,0,0,-1,0,-1,0,-1,0,-1,-1},
                                        {-1,-1,0,-1,0,-1,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0},
                                        {-1,-1,-1,0,-1,-1,-1,0,-1,0,-1,-1,0,-1,0,-1,0,-1,-1,0},
                                        {-1,0,0,0,-1,-1,0,-1,-1,0,-1,0,-1,-1,-1,0,-1,0,-1,-1},
                                         {-1,-1,0,-1,0,-1,-1,0,-1,0,-1,0,-1,0,-1,-1,-1,0,0,-1},
                                         {-1,-1,-0,-1,-1,0,-1,0,-1,0,-1,-1,-1,0,-1,-1,-1,0,-1,0},
                                         {0,0,0,-1,0,-1,-1,0,-1,-1,-1,0,-1,0,-1,0,-1,0,-1,0,-1},
				                         {0,-1,0,-1,0,-1,-1,0,-1,0,-1,-1,-1,0,-1,0,-1,0,0,-1},
				                         {1,-1,0,-1,0,0,0,0,-1,-1,-1,0,-1,0,-1,0,-1,-1,0,-1},
				                         {0,-1,-1,0,0,-1,-1,-1,0,0,-1,-1,0,-1,0,-1,-1,-1,-1,0},
					                     {-1,-1,-1,0,-1,-1,0,-1,-1,0,-1,0,-1,-1,-1,0,-1,0,0,-1},
					                     {-1,0,0,0,0,-1,-1,-0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,-1},
					                     {-1,0,-1,-1,0,-1,-1,0,-1,0,-1,0,-1,0,-1,0,0,0,-1,0},
					                    {-1,0,-1,-1,-1,0,0,-1,-1,-1,-1,-1,-1,-1,-1,0,-1,0,-1,0},
					                    {-1,-1,0,-1,0,-1,-1,-0,-1,0,-1,0,-1,0,-1,-1,-1,-1,-1,0},
		                                {-1,-1,-1,0,-1,0,-1,-1,0,0,-1,-1,0,-1,0,-1,0,-1,-1,-1}};
			  
			return maze;
			}
			else
			{
				int[][] maze = new int[][] {{-1,2,-1,0,-1,-1,-1,-1,0,-1,-1,-1,0,-1,0,0,0,0,-1,0},  
	                    {-1,-1,0,-1,0,-1,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,-1},
	                    {-1,-1,0,-1,0,-1,-1,0,-1,0,-1,0,-1,0,-1,-1,-1,-1,0,-1},
                        {-1,0,0,0,-1,-1,0,-1,-1,0,-1,0,-1,-1,-1,0,-1,0,0,-1},
                        {0,0,0,-1,0,-1,-1,-0,-1,0,0,0,-1,0,-1,0,-1,0,-1,-1},
                        {-1,-1,0,-1,0,-1,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0},
                        {-1,-1,-1,0,-1,-1,-1,0,0,-1,-1,-1,0,-1,0,-1,0,-1,-1,0},
                        {-1,0,0,0,-1,-1,0,-1,-1,0,-1,0,-1,-1,-1,0,-1,0,-1,-1},
                         {-1,-1,0,-1,0,-1,-1,0,-1,0,-1,0,-1,0,-1,-1,-1,0,0,-1},
                         {-1,-1,-0,-1,-1,0,-1,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,-1,0},
                         {0,0,0,-1,0,-1,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1},
                          {0,-1,0,-1,0,-1,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,0,-1},
                    {-1,-1,0,-1,0,-1,-1,0,-1,-1,-1,0,-1,-1,-1,0,-1,-1,0,-1},
                    {0,-1,-1,0,0,-1,0,-1,0,0,-1,-1,0,-1,0,-1,-1,-1,-1,0},
	                   {-1,0,-1,0,-1,-1,0,-1,-1,0,-1,0,-1,-1,-1,0,-1,0,0,-1},
	                  {-1,0,0,0,0,-1,0,-0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,-1},
	                 {-1,0,0,-1,0,-1,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0},
	                    {-1,0,-1,-1,-1,0,0,0,-1,-1,-1,0,-1,-1,-1,0,-1,0,-1,0},
	                {-1,0,0,-1,0,-1,-1,-0,-1,0,-1,0,-1,0,-1,-1,-1,-1,-1,0},
                    {-1,-1,-1,0,-1,0,-1,-1,0,0,0,-1,0,-1,0,-1,0,-1,-1,-1}};
			return maze;
			}
			}

		@Override
		public int connectToServer() {
			return 0;
			// TODO Auto-generated method stub
			
		}

		@Override
		public void changeSong() {
			// TODO Auto-generated method stub
			
		}		
		
		
	}
	
